from rest_framework import serializers
from .models import User
from django.core.exceptions import ValidationError

class UsersSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = '__all__'

# class UsersSerializer(serializers.Serializer):
#     ## 在模型里面我们是没有定义 id 字段的，model 会自动增加 id 字段
#     ## 如果你想在查询数据时需要返回 id 字段，就需要在序列化这里加上 id 字段
#     ## 加上 read_only 则在新建数据时，表单可以不提交 id 字段数据，就算你提交了 id 字段数据，它也会忽略
#     id = serializers.IntegerField(read_only=True)
#     username = serializers.CharField(required=True, max_length=32, min_length=2)
#     password = serializers.CharField(required=True, max_length=256)
#     phone = serializers.CharField(required=True, max_length=15, min_length=11)
#     email = serializers.EmailField(required=True, max_length=32, min_length=3)
#     last_login = serializers.DateTimeField(required=False, read_only=True)
#     add_date = serializers.DateTimeField(required=False, read_only=True)
#     mod_date = serializers.DateTimeField(required=False, read_only=True)
#
#     def create(self, validated_data):
#         createObj = User.objects.create(**validated_data)
#         return createObj
#
#     '''
#         1、put 和 patch 时，api 接口必须要加上 pk ，不然不知道你需要更新或修改哪条数据
#             例如：http://localhost/apis/user/1/，表示更新 id 为 1 的这条数据
#         2、put 是修改数据，所有字段都必须传
#            patch 是更新数据，可以更新任意字段，表单没传的字段就保持原来的值
#     '''
#     def update(self, instance, validated_data):
#         instance.username = validated_data.get('username', instance.username)
#         instance.password = validated_data.get('password', instance.password)
#         instance.phone = validated_data.get('phone', instance.phone)
#         instance.email = validated_data.get('email', instance.email)
#         ## 因为上面序列化验证是 read_only 所以就算你表单有写这个字段，这个字段也不会更改
#         instance.last_login = validated_data.get('last_login', instance.last_login)
#         instance.save()
#         return instance

'''
使用模型序列化，可以自定义字段检验逻辑
比如用做登录接口时，我只想校验 username 和 password 字段
'''
class LoginSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        # fields = '__all__'  # 或者列出所有需要的字段
        fields = ["username", "password", "email"]

        '''
            如果对字段的校验有更细的需求，可以通过 extra_kwargs 来实现，
            因为上面通过 fields 来指定要校验的字段，最小颗粒度是字段，
            但是extra_kwargs 可以更细到字段属性
        '''
        extra_kwargs = {
            'username': {  # 替换为你的字段名
                'required': False,  # 设置为False来跳过该字段的必填验证
                # 'allow_null': True,  # 如果字段允许为NULL，还可以加上这一行
                # 'default': some_default_value  # 如果需要，可以提供一个默认值
            },
            'email': {  # 替换为你的字段名
                'required': False,  # 设置为False来跳过该字段的必填验证
                # 'allow_null': True,  # 如果字段允许为NULL，还可以加上这一行
                # 'default': some_default_value  # 如果需要，可以提供一个默认值
            },
            # 可以添加更多字段及其配置
        }

    # 添加一个方法来控制特定字段的验证
    def skip_field_validation(self, validated_data, fields_to_skip):
        for field in fields_to_skip:
            if field in validated_data:
                del validated_data[field]  # 从validated_data中移除该字段，跳过校验
        return validated_data

    ## 重写校验规则
    def validate(self, attrs):
        # 确保username和email中至少有一个字段有值
        if not (attrs.get('username') or attrs.get('email')):
            raise ValidationError("至少需要提供username或email。")

        # 如果你的模型中有其他字段需要验证，可以在此处添加相应的逻辑
        return attrs


    # def update(self, instance, validated_data):
    #     # 在更新模型实例前，可以在这里决定是否跳过某些字段的校验
    #     # 示例中直接调用了skip_field_validation方法
    #     validated_data = self.skip_field_validation(validated_data, 'field_to_skip')
    #     return super().update(instance, validated_data)